﻿using System;
using System.Windows;
using System.Windows.Media;

namespace Telerik.Windows.Documents.Utilities
{
    // TODO: This class is literally copied and pasted from Telerik.Windows.Maths! Rethink if this is a good idea?!
    internal static class AlgebraExtensions
    {
        public const double Epsilon = 1E-8;

        public static Point MultiplyBy(this Point a, double number)
        {
            return new Point(a.X * number, a.Y * number);
        }

        public static double MultiplyBy(this Point a, Point other)
        {
            return a.X * other.X + a.Y * other.Y;
        }

        public static double Length(this Point a)
        {
            return Math.Sqrt(a.MultiplyBy(a));
        }

        public static bool IsZero(this Point a)
        {
            return a.Length() < Epsilon;
        }

        public static Point UnitVector(this Point a)
        {
            if (a.IsZero())
            {
                throw new ArgumentException("Cannot calculate unit vector of a point with zero length!");
            }

            return a.MultiplyBy(1 / a.Length());
        }

        //public static Matrix MultiplyBy(this Matrix m1, Matrix m2)
        //{
        //    ////F# would be handy here...
        //    return new Matrix(
        //        (m1.M11 * m2.M11) + (m1.M12 * m2.M21), (m1.M11 * m2.M12) + (m1.M12 * m2.M22),
        //        (m1.M21 * m2.M11) + (m1.M22 * m2.M21), (m1.M21 * m2.M12) + (m1.M22 * m2.M22), // Fucking mistake!!!
        //        (m1.OffsetX * m2.M11) + (m1.OffsetY * m2.M21) + m2.OffsetX, (m1.OffsetX * m2.M12) + (m1.OffsetY * m2.M22) + m2.OffsetY);
        //}

        //public static Matrix ScaleMatrix(this Matrix matrix, double scaleX, double scaleY, double centerX = 0, double centerY = 0)
        //{
        //    return new Matrix(scaleX, 0, 0, scaleY, centerX, centerY).MultiplyBy(matrix);
        //}

        //public static Matrix RotateMatrixAt(this Matrix matrix, double angleInDegrees, double centerX, double centerY)
        //{
        //    double angle = Math.PI * angleInDegrees / 180;
        //    double sin = Math.Sin(angle);
        //    double cos = Math.Cos(angle);
        //    double offsetX = (centerX * (1.0 - cos)) + (centerY * sin);
        //    double offsetY = (centerY * (1.0 - cos)) - (centerX * sin);
        //    Matrix rotationMatrix = new Matrix(cos, sin, -sin, cos, offsetX, offsetY);

        //    return rotationMatrix.MultiplyBy(matrix);
        //}

        //public static Matrix RotateMatrix(this Matrix m, double angleInDegrees)
        //{
        //    double radians = Math.PI * angleInDegrees / 180;

        //    double sin = Math.Sin(radians);
        //    double cos = Math.Cos(radians);

        //    double m11 = m.M11;
        //    double m12 = m.M12;
        //    double m21 = m.M21;
        //    double m22 = m.M22;
        //    double offsetX = m.OffsetX;
        //    double offsetY = m.OffsetY;

        //    m.M11 = m11 * cos - m12 * sin;
        //    m.M12 = m11 * sin + m12 * cos;
        //    m.M21 = m21 * cos - m22 * sin;
        //    m.M22 = m21 * sin + m22 * cos;
        //    m.OffsetX = offsetX * cos - offsetY * sin;
        //    m.OffsetY = offsetX * sin + offsetY * cos;

        //    return m;
        //}

        //public static Matrix TranslateMatrix(this Matrix m, double deltaX, double deltaY)
        //{
        //    m.OffsetX += deltaX;
        //    m.OffsetY += deltaY;

        //    return m;
        //}

        //public static Matrix InverseMatrix(this Matrix m)
        //{
        //    ////just basic algebra
        //    var det = (m.M11 * m.M22) - (m.M12 * m.M21);
        //    var det1 = 1 / det;
        //    return new Matrix(m.M22 * det1, -m.M12 * det1, -m.M21 * det1, m.M11 * det1, ((m.M21 * m.OffsetY) - (m.OffsetX * m.M22)) * det1, ((m.OffsetX * m.M12) - (m.M11 * m.OffsetY)) * det1);
        //}
    }
}
